package com.ruoyi.system.minio;

import io.minio.*;
import io.minio.http.Method;
import io.minio.messages.Item;
import org.apache.poi.util.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@Service
public class MinioService {

    @Autowired
    private MinioClient minioClient;

    @Autowired
    private MinioConfig minioConfig;

    /**
     * 上传文件
     */
    public String uploadFile(MultipartFile file) throws Exception {
        String originalFilename = file.getOriginalFilename();
        String fileName = generateFileName(originalFilename);

        // 上传文件
        minioClient.putObject(PutObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .stream(file.getInputStream(), file.getSize(), -1)
                .contentType(file.getContentType())
                .build());

        return fileName;
    }

    /**
     * 下载文件
     */
    public byte[] downloadFile(String fileName) throws Exception {
        try (InputStream stream = minioClient.getObject(GetObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .build())) {

            return IOUtils.toByteArray(stream);
        }
    }

    /**
     * 获取文件信息
     */
    public StatObjectResponse getFileInfo(String fileName) throws Exception {
        return minioClient.statObject(StatObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .build());
    }

    /**
     * 删除文件
     */
    public void deleteFile(String fileName) throws Exception {
        minioClient.removeObject(RemoveObjectArgs.builder()
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .build());
    }

    /**
     * 获取文件预览URL
     */
    public String getPreviewUrl(String fileName) throws Exception {
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.GET)
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .expiry(60 * 60) // 1小时有效期
                .build());
    }

    /**
     * 获取直接上传URL（前端直传）
     */
    public String getPresignedPutUrl(String fileName) throws Exception {
        return minioClient.getPresignedObjectUrl(GetPresignedObjectUrlArgs.builder()
                .method(Method.PUT)
                .bucket(minioConfig.getBucketName())
                .object(fileName)
                .expiry(60 * 10) // 10分钟有效期
                .build());
    }

    /**
     * 列出存储桶中的所有文件
     */
    public List<String> listFiles() throws Exception {
        List<String> fileNames = new ArrayList<>();

        Iterable<Result<Item>> results = minioClient.listObjects(ListObjectsArgs.builder()
                .bucket(minioConfig.getBucketName())
                .build());

        for (Result<Item> result : results) {
            Item item = result.get();
            fileNames.add(item.objectName());
        }

        return fileNames;
    }

    /**
     * 生成唯一文件名
     */
    private String generateFileName(String originalFileName) {
        String fileExtension = "";
        if (originalFileName != null && originalFileName.contains(".")) {
            fileExtension = originalFileName.substring(originalFileName.lastIndexOf("."));
        }
        return UUID.randomUUID().toString().replace("-", "") + fileExtension;
    }
}
